﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI;
using Telerik.Web.UI;
using System.Xml.Linq;
using System.Web;

namespace RN.ERP.Web.Exam
{
    public partial class BmDownloadManage : System.Web.UI.Page
    {
        #region Params
        
        private const int MAX_UPLOAD_SIZE = 10;

        #endregion

        protected void Page_Load(object sender, EventArgs e)
        {

        }

        /// <summary>
        /// 文件处理 （增删改）
        /// </summary>
        protected void btnUpload_Click(object sender, EventArgs e)
        {
            string opType = hidOperaType.Value;
            switch (opType)
            {
                case "add": AddFile(); break;
                case "replace": ReplaceFile(); break;
                case "del": DelFile(); break;
                default: break;
            }
        }

        private void DelFile() 
        {
            string id = hidFileID.Value;
            if (FileStoreManager.Delete(id))
            {
                ExecScript("OpenAlert('文件删除成功。',RefreshWin)");
            }
            else
            {
                ExecScript("OpenAlert('文件删除失败。')");
            }
        }

        /// <summary>
        /// 替换文件
        /// </summary>
        private void ReplaceFile()
        {
            if (uploadFile.PostedFile.ContentLength > MAX_UPLOAD_SIZE * 1024 * 1024)
            {
                ExecScript(String.Format("OpenAlert('请上传{0}M以内的文件。')", MAX_UPLOAD_SIZE));
                return;
            }

            string guid = Guid.NewGuid().ToString();
            string fileShowName = this.txtFileName.Text;////下载页面看到的文件名
            string uploadFileName = this.uploadFile.PostedFile.FileName;////上传时的文件名
            string suffix = uploadFileName.Substring(uploadFileName.LastIndexOf("."));
            string saveFileName = guid + suffix;////保存后的文件名
            string path = Server.MapPath(saveFileName);

            TestFile file = new TestFile
            {
                ID=hidFileID.Value,
                ModifyDate = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"),
                Name = fileShowName,
                Suffix = suffix,
                IsDel="false",
                Path = saveFileName
            };

            if (FileStoreManager.Update(file))
            {
                this.uploadFile.PostedFile.SaveAs(path);
                ExecScript("OpenAlert('文件添加成功。',RefreshWin)");
            }
            else
            {
                ExecScript("OpenAlert('文件添加失败。')");
            }
        }

        /// <summary>
        /// 添加文件
        /// </summary>
        private void AddFile()
        {
            if (uploadFile.PostedFile.ContentLength > MAX_UPLOAD_SIZE*1024*1024)
            {
                ExecScript(String.Format("OpenAlert('请上传{0}M以内的文件。')", MAX_UPLOAD_SIZE));
                return;
            }
            
            string guid = Guid.NewGuid().ToString();
            string fileShowName = this.txtFileName.Text;////下载页面看到的文件名
            string uploadFileName = this.uploadFile.PostedFile.FileName;////上传时的文件名
            string suffix = uploadFileName.Substring(uploadFileName.LastIndexOf("."));
            string saveFileName = guid + suffix;////保存后的文件名
            string path = Server.MapPath(saveFileName);

            TestFile file = new TestFile
            {
                ID = guid,
                IsDel = "false",
                ModifyDate = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"),
                Name = fileShowName,
                Suffix = suffix,
                Path = saveFileName
            };

            if (FileStoreManager.Add(file))
            {
                this.uploadFile.PostedFile.SaveAs(path);
                ExecScript("OpenAlert('文件添加成功。',RefreshWin)");
            }
            else
            {
                ExecScript("OpenAlert('文件添加失败。')");
            }
        }

        protected void fileListGrid_NeedDataSource(object source, GridNeedDataSourceEventArgs e)
        {
            ////绑定数据源
            BindData();
        }

        /// <summary>
        /// 数据绑定
        /// </summary>
        private void BindData()
        {
            fileListGrid.AllowCustomPaging = true;
            
            List<TestFile> files = FileStoreManager.GetAllFile();
            fileListGrid.VirtualItemCount = files.Count;
            fileListGrid.DataSource = files;
        }

        /// <summary>
        /// 执行Js脚本
        /// </summary>
        /// <param name="script">脚本文本</param>
        private void ExecScript(string script)
        {
            ClientScript.RegisterStartupScript(Page.GetType(), "", String.Format("<script>{0}</script>", script));
        }
    }

    public class FileStoreManager
    {
        private static string CONFIG_FILE_PATH = "Exam/FileStore.xml";
        private static XDocument doc;
        private static List<TestFile> FileCache;
        private static readonly object _lock = new object();////因为只有省主管能改变文件，所以就不需要做锁了

        static FileStoreManager()
        {
            doc = XDocument.Load(AppDomain.CurrentDomain.BaseDirectory + CONFIG_FILE_PATH);
            if (FileCache == null)
            {
                CacheRebuild();
            }
        }

        private static void Save()
        {
            doc.Save(AppDomain.CurrentDomain.BaseDirectory + CONFIG_FILE_PATH);
        }
        public static bool Add(TestFile file)
        {
            try
            {
                var ele = new XElement("File");
                ele.SetAttributeValue("ID", file.ID);
                ele.SetAttributeValue("ModifyDate", file.ModifyDate);
                ele.SetAttributeValue("Name", file.Name);
                ele.SetAttributeValue("Suffix", file.Suffix);
                ele.SetAttributeValue("Path", file.Path);
                ele.SetAttributeValue("IsDel", "false");
                doc.Root.Add(ele);
                Save();
                FileCache.Add(file);
                return true;
            }
            catch (Exception ex)
            {

            }
            return false;
        }
        public static bool Update(TestFile file)
        {
            try
            {
                var ele = doc.Root.Elements("File").FirstOrDefault(e=>e.Attribute("ID").Value==file.ID);
                
                if(ele!=null)
                {
                    ele.SetAttributeValue("ModifyDate", file.ModifyDate);
                    ele.SetAttributeValue("Name", file.Name);
                    ele.SetAttributeValue("Suffix", file.Suffix);
                    ele.SetAttributeValue("Path", file.Path);
                    Save();
                    int index = FileCache.FindIndex(f => f.ID == file.ID);
                    FileCache[index] = file;
                    return true;
                }                    
            }
            catch (Exception ex)
            {

            }
            return false;
        }
        public static bool Delete(string id)
        {
            try
            {
                var ele = doc.Root.Elements("File").FirstOrDefault(e => e.Attribute("ID").Value == id);
                
                if (ele != null)
                {
                    ele.SetAttributeValue("IsDel", "true");
                    ele.SetAttributeValue("ModifyDate", DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"));
                    Save();
                    int index = FileCache.FindIndex(f => f.ID == id);
                    FileCache.RemoveAt(index);
                    return true;
                }
            }
            catch (Exception ex)
            {
                
            }
            return false;
        }
        public static List<TestFile> GetAllFile()
        {
            return FileCache;
        }
        public static TestFile GetFile(string id)
        {
            TestFile file = FileCache.FirstOrDefault(f=>f.ID==id);
            return file;
        }

        private static void CacheRebuild()
        {
            FileCache = doc.Root.Elements("File")
                .Where(e => e.Attribute("IsDel").Value == "false")
                .Select<XElement, TestFile>(fileEle => new TestFile
                {
                    ID = fileEle.Attribute("ID").Value,
                    Name = fileEle.Attribute("Name").Value,
                    Suffix = fileEle.Attribute("Suffix").Value,
                    Path = fileEle.Attribute("Path").Value,
                    ModifyDate = fileEle.Attribute("ModifyDate").Value,
                }).ToList();
        }
    }

    public class TestFile
    {
        public string ID{set;get;}
        public string Name { set; get; }
        public string ModifyDate { set; get; }
        public string Path { set; get; }
        public string Suffix { set; get; }
        public string IsDel { set; get; }
    }
}